#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
PyInstaller打包配置脚本
用于将MP4视频压缩工具打包成独立的exe程序
"""

import os
import sys
import shutil
import subprocess
from pathlib import Path

# 项目信息
APP_NAME = "MP4VideoCompressor"
APP_VERSION = "1.0.0"
APP_DESCRIPTION = "MP4视频压缩工具"
APP_AUTHOR = "AI助手"

# 打包配置
BUILD_CONFIG = {
    "name": APP_NAME,
    "script": "main.py",
    "icon": None,  # 可以添加图标文件路径
    "console": False,  # 不显示控制台窗口
    "onefile": True,   # 打包成单个exe文件
    "windowed": True,  # Windows应用程序
    "clean": True,     # 清理临时文件
}

# 需要包含的数据文件和目录
INCLUDE_DATA = [
    ("config", "config"),
    ("gui", "gui"), 
    ("core", "core"),
    ("utils", "utils"),
    ("README.md", "."),
    ("用户手册.md", "."),
]

# 需要包含的Python模块
HIDDEN_IMPORTS = [
    "tkinter",
    "tkinter.ttk",
    "tkinter.filedialog",
    "tkinter.messagebox",
    "ffmpeg",
    "psutil",
    "threading",
    "subprocess",
    "platform",
    "re",
    "time",
    "os",
    "sys",
]

# 排除的模块（减小文件大小）
EXCLUDES = [
    "matplotlib",
    "numpy",
    "scipy",
    "pandas",
    "PIL",
    "cv2",
    "tensorflow",
    "torch",
    "jupyter",
    "IPython",
]

def create_spec_file():
    """创建PyInstaller spec文件"""
    spec_content = f'''# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

# 数据文件配置
datas = {INCLUDE_DATA}

# 分析配置
a = Analysis(
    ['{BUILD_CONFIG["script"]}'],
    pathex=[],
    binaries=[],
    datas=datas,
    hiddenimports={HIDDEN_IMPORTS},
    hookspath=[],
    hooksconfig={{}},
    runtime_hooks=[],
    excludes={EXCLUDES},
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

# PYZ配置
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

# EXE配置
exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='{BUILD_CONFIG["name"]}',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console={BUILD_CONFIG["console"]},
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    version='version_info.txt',
)
'''
    
    with open(f"{APP_NAME}.spec", "w", encoding="utf-8") as f:
        f.write(spec_content)
    
    print(f"✅ 创建spec文件: {APP_NAME}.spec")

def create_version_info():
    """创建版本信息文件"""
    version_info = f'''# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
  ffi=FixedFileInfo(
    filevers=(1,0,0,0),
    prodvers=(1,0,0,0),
    mask=0x3f,
    flags=0x0,
    OS=0x40004,
    fileType=0x1,
    subtype=0x0,
    date=(0, 0)
    ),
  kids=[
    StringFileInfo(
      [
      StringTable(
        u'040904B0',
        [StringStruct(u'CompanyName', u'{APP_AUTHOR}'),
        StringStruct(u'FileDescription', u'{APP_DESCRIPTION}'),
        StringStruct(u'FileVersion', u'{APP_VERSION}'),
        StringStruct(u'InternalName', u'{APP_NAME}'),
        StringStruct(u'LegalCopyright', u'Copyright © 2024 {APP_AUTHOR}'),
        StringStruct(u'OriginalFilename', u'{APP_NAME}.exe'),
        StringStruct(u'ProductName', u'{APP_DESCRIPTION}'),
        StringStruct(u'ProductVersion', u'{APP_VERSION}')])
      ]), 
    VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
  ]
)
'''
    
    with open("version_info.txt", "w", encoding="utf-8") as f:
        f.write(version_info)
    
    print("✅ 创建版本信息文件: version_info.txt")

def check_dependencies():
    """检查依赖是否完整"""
    print("检查项目依赖...")
    
    required_files = [
        "main.py",
        "config/settings.py",
        "core/compressor.py",
        "gui/main_window.py",
        "utils/file_handler.py",
    ]
    
    missing_files = []
    for file in required_files:
        if not os.path.exists(file):
            missing_files.append(file)
    
    if missing_files:
        print("❌ 缺少必要文件:")
        for file in missing_files:
            print(f"   - {file}")
        return False
    
    print("✅ 所有必要文件都存在")
    return True

def build_executable():
    """构建可执行文件"""
    print("开始构建可执行文件...")
    
    try:
        # 使用PyInstaller构建
        cmd = [
            "pyinstaller",
            "--clean",
            f"{APP_NAME}.spec"
        ]
        
        print(f"执行命令: {' '.join(cmd)}")
        result = subprocess.run(cmd, capture_output=True, text=True)
        
        if result.returncode == 0:
            print("✅ 构建成功!")
            
            # 检查输出文件
            exe_path = f"dist/{APP_NAME}.exe"
            if os.path.exists(exe_path):
                file_size = os.path.getsize(exe_path)
                print(f"✅ 生成的exe文件: {exe_path}")
                print(f"   文件大小: {file_size / 1024 / 1024:.2f} MB")
                return True
            else:
                print("❌ 未找到生成的exe文件")
                return False
        else:
            print("❌ 构建失败:")
            print(result.stderr)
            return False
            
    except Exception as e:
        print(f"❌ 构建过程出错: {str(e)}")
        return False

def create_installer_script():
    """创建安装脚本"""
    installer_script = f'''@echo off
echo ========================================
echo {APP_DESCRIPTION} 安装程序
echo 版本: {APP_VERSION}
echo ========================================
echo.

REM 检查FFmpeg
echo 检查FFmpeg是否已安装...
ffmpeg -version >nul 2>&1
if %errorlevel% neq 0 (
    echo [错误] 未检测到FFmpeg
    echo.
    echo 请先安装FFmpeg:
    echo 1. 访问 https://ffmpeg.org/download.html
    echo 2. 下载Windows版本
    echo 3. 解压并添加到系统PATH
    echo 4. 重新运行此安装程序
    echo.
    pause
    exit /b 1
) else (
    echo [成功] FFmpeg已安装
)

echo.
echo 安装完成！
echo.
echo 使用说明:
echo 1. 双击 {APP_NAME}.exe 启动程序
echo 2. 选择要压缩的MP4视频文件
echo 3. 选择输出目录和压缩质量
echo 4. 点击"开始压缩"
echo.
echo 注意事项:
echo - 确保有足够的磁盘空间
echo - 大文件压缩需要较长时间
echo - 可以随时停止压缩过程
echo.
pause
'''
    
    with open("install.bat", "w", encoding="utf-8") as f:
        f.write(installer_script)
    
    print("✅ 创建安装脚本: install.bat")

def create_readme():
    """创建发布说明"""
    readme_content = f'''# {APP_DESCRIPTION} v{APP_VERSION}

## 📦 发布包内容

- `{APP_NAME}.exe` - 主程序（独立运行）
- `install.bat` - 安装检查脚本
- `README_发布版.txt` - 使用说明

## 🚀 快速开始

### 1. 系统要求
- Windows 10/11 (64位)
- 需要安装FFmpeg

### 2. FFmpeg安装
如果您还没有安装FFmpeg，请按以下步骤操作：

1. 访问 https://ffmpeg.org/download.html
2. 下载Windows版本
3. 解压到任意目录（如 C:\\ffmpeg）
4. 将bin目录添加到系统PATH环境变量
5. 重启命令提示符验证：`ffmpeg -version`

### 3. 运行程序
1. 双击运行 `install.bat` 检查环境
2. 双击运行 `{APP_NAME}.exe` 启动程序
3. 按照界面提示操作

## 📋 功能特点

- ✅ 支持MP4格式视频压缩
- ✅ 批量处理多个视频文件  
- ✅ 硬件加速支持（GPU）
- ✅ 实时进度显示和时间预估
- ✅ 多种压缩质量预设
- ✅ 智能性能优化

## 🎯 使用步骤

1. **选择文件**: 点击"选择视频文件"选择MP4文件
2. **选择输出**: 点击"选择输出目录"设置保存位置
3. **选择质量**: 从下拉菜单选择压缩质量
4. **开始压缩**: 点击"开始压缩"按钮
5. **等待完成**: 观察进度和剩余时间

## ⚙️ 压缩质量说明

- **极速压缩**: 最快速度，适合大文件
- **快速高质量**: 速度和质量的最佳平衡
- **高质量**: 保持较高画质
- **中等质量**: 平衡画质和文件大小
- **小文件**: 最小文件大小

## 🔧 性能优化

程序会自动检测您的硬件配置：
- 如果有NVIDIA/AMD/Intel GPU，会自动启用硬件加速
- 自动优化多线程设置
- 智能调整CPU使用率

## ❓ 常见问题

**Q: 程序无法启动？**
A: 请确保已安装FFmpeg并添加到系统PATH

**Q: 压缩速度很慢？**
A: 尝试选择"极速压缩"模式，或检查是否启用了GPU加速

**Q: 压缩后文件很大？**
A: 尝试选择"小文件"预设，或调整压缩质量

## 📞 技术支持

如果遇到问题，请检查：
1. FFmpeg是否正确安装
2. 输入文件是否为有效的MP4格式
3. 输出目录是否有足够空间
4. 系统是否有足够内存

---
版本: {APP_VERSION} | 构建日期: {{build_date}}
'''
    
    import datetime
    build_date = datetime.datetime.now().strftime("%Y-%m-%d")
    readme_content = readme_content.format(build_date=build_date)
    
    with open("README_发布版.txt", "w", encoding="utf-8") as f:
        f.write(readme_content)
    
    print("✅ 创建发布说明: README_发布版.txt")

def cleanup_build_files():
    """清理构建临时文件"""
    cleanup_dirs = ["build", "__pycache__"]
    cleanup_files = [f"{APP_NAME}.spec", "version_info.txt"]
    
    for dir_name in cleanup_dirs:
        if os.path.exists(dir_name):
            shutil.rmtree(dir_name)
            print(f"🧹 清理目录: {dir_name}")
    
    for file_name in cleanup_files:
        if os.path.exists(file_name):
            os.remove(file_name)
            print(f"🧹 清理文件: {file_name}")

def main():
    """主函数"""
    print("=" * 60)
    print(f"{APP_DESCRIPTION} - 打包构建工具")
    print("=" * 60)
    
    # 检查依赖
    if not check_dependencies():
        return False
    
    # 创建配置文件
    create_spec_file()
    create_version_info()
    
    # 构建可执行文件
    if build_executable():
        # 创建发布文件
        create_installer_script()
        create_readme()
        
        print("\n" + "=" * 60)
        print("🎉 打包完成!")
        print("=" * 60)
        print(f"✅ 可执行文件: dist/{APP_NAME}.exe")
        print(f"✅ 安装脚本: install.bat")
        print(f"✅ 使用说明: README_发布版.txt")
        
        print("\n📦 发布步骤:")
        print("1. 将dist目录中的exe文件复制出来")
        print("2. 连同install.bat和README_发布版.txt一起打包")
        print("3. 分发给用户使用")
        
        # 询问是否清理临时文件
        response = input("\n是否清理构建临时文件? (y/n): ").strip().lower()
        if response in ['y', 'yes', '是']:
            cleanup_build_files()
        
        return True
    else:
        print("\n❌ 打包失败")
        return False

if __name__ == "__main__":
    main()
